<style lang="scss" scoped>
.virtual-list-container{
    height: 300px;
    overflow-y: auto;
    border: 1px solid #ccc;
}

.list-item{
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-bottom: 1px solid #666;
}

</style>

<template>
    <div ref="container" class="virtual-list-container">
        <div v-for="item in visibleItems" :key="item.id" class="list-item">
            {{ item.name }}
        </div>
    </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted } from 'vue'
import { computed } from 'vue'
interface ListItem {
    id: number,
    name: string,
}

export default defineComponent({
    props: {
        items: {
            type: Array as () => ListItem[],
            required: true
        },
        itemHeight: {
            type: Number,
            default: 50
        }
    },
    setup(props) {
        const container = ref<HTMLElement | null >(null)
        const startIndex = ref(0)
        const endIndex = ref(0)
        // 计算可视区域内的条目
        const visibleItems = computed(() => {
            return props.items.slice(startIndex.value, endIndex.value)
        })
        console.log(visibleItems.value);
        
        // 监听滚动事件
        const handleScroll = () => {
            if (container.value) {
                const scrollTop = container.value.scrollTop
                const offsetHeight = container.value.offsetHeight
                const totalHeight = container.value.scrollHeight
                // 计算可视区域的起始索引
                startIndex.value = Math.floor(scrollTop / props.itemHeight)
                // 计算可视化区域的结束索引
                endIndex.value = startIndex.value + Math.ceil(offsetHeight / props.itemHeight)

                // 如果接近底部，可以触发更多逻辑
                if (scrollTop + offsetHeight >= totalHeight - props.itemHeight) {
                    console.log('接近底部，可以加载更多');
                }
            }
        };
        onMounted(() => {
            if (container.value) {
                container.value.addEventListener('scroll', handleScroll)
            }
        })
        onUnmounted(() => {
            if (container.value) {
                container.value.removeEventListener('scroll', handleScroll)
            }
        })
        return {
            container,
            visibleItems
        }
    }
})

</script>